package com.tenpines.test.helper;

import java.io.IOException;
import java.util.Properties;

import org.hamcrest.Description;
import org.hamcrest.StringDescription;

/**
 * @author egutter
 * 
 */
public class AsyncTestHelper {

	private static final String SAMPLING_DELAY_PROPERTY = "sampling.delay";

	private static final String TIMEOUT_PROPERTY = "test.timeout";

	private static final String PROPERTIES_FILE_NAME = "async-tests.properties";

	private static long timeoutMillis;

	private static long pollDelayMillis;

	static {
		Properties asyncProprs = new Properties();
		try {
			asyncProprs.load(AsyncTestHelper.class
					.getResourceAsStream(PROPERTIES_FILE_NAME));
			timeoutMillis = Long.parseLong(asyncProprs
					.getProperty(TIMEOUT_PROPERTY));
			pollDelayMillis = Long.parseLong(asyncProprs
					.getProperty(SAMPLING_DELAY_PROPERTY));
		} catch (IOException e) {
			throw new IllegalStateException(e);
		}
	}

	public static void assertEventually(AsyncCondition condition) {
		try {
			new AsyncTestHelper().check(condition);
		} catch (InterruptedException e) {
			throw new RuntimeException(e);
		}
	}

	private void check(AsyncCondition condition) throws InterruptedException {
		Timeout timeout = new Timeout(timeoutMillis);
		while (!condition.isSatisfied()) {

			if (timeout.hasTimedOut()) {
				throw new AssertionError(describeFailureOf(condition));
			}
			Thread.sleep(pollDelayMillis);
			condition.sample();
		}
	}

	private String describeFailureOf(AsyncCondition condition) {
		Description description = new StringDescription();
		condition.describeFailureTo(description);
		return description.toString();
	}

}
